# XXX: unicode()s due to "can't adapt" error in psycopg2, which
# doesn't like <class 'suds.sax.text.Text'>

import ourcity.reps.cicero_lookup as lookup
from django.contrib.auth.models import User
from django.core.mail import mail_managers
from django import forms
from django.contrib.localflavor.us.forms import USStateField, USStateSelect
from django.template import loader
from ourcity.core.models import Profile

ATTRS_DICT = {'class': 'text'}

#class CreateProfileForm(forms.ModelForm):
#    class Meta:
#        model = Profile
#        # User will be filled in by the view and districts will be filled
#        # in by lookup.
#        exclude = ('user', 'districts') 

class CreateProfileForm(forms.Form):
    first_name = forms.CharField(widget=forms.TextInput(attrs=ATTRS_DICT),
            required=False)
    last_name = forms.CharField(widget=forms.TextInput(attrs=ATTRS_DICT),
            required=False)
    address = forms.CharField(widget=forms.TextInput(attrs=ATTRS_DICT),
            required=False)
    city = forms.CharField(widget=forms.TextInput(attrs=ATTRS_DICT),
            required=False)
    state = USStateField(widget=USStateSelect, required=False)
    photo = forms.ImageField(required=False)
    email_opt_in = forms.BooleanField(initial=True)

    # commit parameter needed for django-profiles view
    def save(self, commit=False):
        address = self.cleaned_data['address']
        city = self.cleaned_data['city']
        state = self.cleaned_data['state']
        email_opt_in = self.cleaned_data['email_opt_in']
        if address:
            cc = lookup.CiceroConnection()
            location, self.districts = cc.query_address(address, city, state)
        else:
            location, self.districts = (None, [])
        if location:
            self.instance = Profile(
                address=address,
                standardized_address=unicode(location.StandardizedAddress),
                city=city,
                state=state,
                postal_code=unicode(location.PostalCode),
                latitude=unicode(location.Latitude),
                longitude=unicode(location.Longitude),
                email_opt_in=email_opt_in,
            )
        else:
            self.instance = Profile(
                address=address,
                city=city,
                state=state,
            )
        if self.cleaned_data['photo']:
            self.instance.photo.save(self.cleaned_data['photo'].name, 
                    self.cleaned_data['photo'], save=False)
        return self.instance

    def save_m2m(self):
        user = self.instance.user
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()
        for district in self.districts:
            self.instance.districts.add(district)


class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        exclude = ('user', 'districts')


class EditProfileForm(ProfileForm):
    first_name = forms.CharField(widget=forms.TextInput(attrs=ATTRS_DICT),
            required=False)
    last_name = forms.CharField(widget=forms.TextInput(attrs=ATTRS_DICT),
            required=False)
    email = forms.EmailField(widget=forms.TextInput(attrs=ATTRS_DICT))
    address = forms.CharField(widget=forms.TextInput(attrs=ATTRS_DICT),
            required=False)
    city = forms.CharField(widget=forms.TextInput(attrs=ATTRS_DICT),
            required=False)
    state = USStateField(widget=USStateSelect,
            required=False)
    password1 = forms.CharField(widget=forms.PasswordInput(attrs=ATTRS_DICT),
            required=False)
    password2 = forms.CharField(widget=forms.PasswordInput(attrs=ATTRS_DICT),
            required=False)
    photo = forms.ImageField(required=False)
    email_opt_in = forms.BooleanField(initial=True)

    def __init__(self, data=None, files=None, initial=None, instance=None):
        user_initial = {
            'first_name': instance.user.first_name,
            'last_name': instance.user.last_name,
            'email': instance.user.email,
        }
        if initial:
            user_initial.update(initial)
        super(EditProfileForm, self).__init__(data=data, files=files, 
                initial=user_initial, instance=instance)

    def clean(self):
        super(EditProfileForm, self).clean()
        if self.cleaned_data['password1'] != self.cleaned_data['password2']:
            raise forms.ValidationError('You must type the same password each time')
        return self.cleaned_data

    def save(self):
        address = self.cleaned_data['address']
        city = self.cleaned_data['city']
        state = self.cleaned_data['state']
        email_opt_in = self.cleaned_data['email_opt_in']
        is_philadelphia = True
        if city.lower().strip() != 'philadelphia':
            is_philadelphia = False
        if state != 'PA':
            is_philadelphia = False
        # Replace districts if anything has changed.
        location = None
        districts = []
        if (address != self.instance.address or city != self.instance.city or 
                state != self.instance.state):
            self.instance.districts.clear()
            if address and is_philadelphia:
                cc = lookup.CiceroConnection()
                location, districts = cc.query_address(address, city, state)
        self.instance.address = address
        self.instance.city = city
        self.instance.state = state
        self.instance.email_opt_in = email_opt_in
        if location:
            self.instance.standardized_address = unicode(
                    location.StandardizedAddress)
            self.instance.postal_code = unicode(location.PostalCode)
            self.instance.latitude = unicode(location.Latitude)
            self.instance.longitude = unicode(location.Longitude)
        for district in districts:
            self.instance.districts.add(district)
        if self.cleaned_data['photo']:
            self.instance.photo.save(self.cleaned_data['photo'].name, 
                    self.cleaned_data['photo'], save=False)
        self.instance.save()
        user = self.instance.user
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.email = self.cleaned_data['email']
        password = self.cleaned_data['password1']
        if password:
            user.set_password(password)
        user.save()

class ContactForm(forms.Form):
    name = forms.CharField(widget=forms.TextInput(attrs=ATTRS_DICT))
    email = forms.EmailField(widget=forms.TextInput(attrs=ATTRS_DICT))
    message = forms.CharField(widget=forms.Textarea)
    honeypot = forms.CharField(required=False)

    def save(self):
        subject = 'Contact via website'
        message = loader.render_to_string('contact_message.txt',
                                          self.cleaned_data)
        mail_managers(subject, message, fail_silently=True)

    def clean_honeypot(self):
        """Check that nothing's been entered into the honeypot."""
        value = self.cleaned_data["honeypot"]
        if value:
            raise forms.ValidationError(self.fields["honeypot"].label)
        return value

